﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using Emporium_Web.Controls;
using Emporium_Web.Enums;
using Emporium_Web.DBML;
using System.Linq.Expressions;

namespace Emporium_Web
{
    public partial class ConsultaAvanceActividades : System.Web.UI.Page
    {
        TablasDataContext database = null;

        public int PrendasProgramadas
        {
            get
            {
                return ViewState["PrendasProgramadas"] == null ? 0 : Convert.ToInt32(ViewState["PrendasProgramadas"].ToString());
            }
            set
            {
                ViewState["PrendasProgramadas"] = value;
            }
        }

        private int ProcesoID
        {
            get { return ViewState["ProcesoID"] == null ? -1 : (int)ViewState["ProcesoID"]; }
            set { ViewState["ProcesoID"] = value; }
        }

        private int ActividadID
        {
            get { return ViewState["ActividadID"] == null ? -1 : (int)ViewState["ActividadID"]; }
            set { ViewState["ActividadID"] = value; }
        }

        private int IdSeleccionado
        {
            get { return (int)ViewState["IdSeleccionado"]; }
            set { }
        }


        [Serializable]
        private class ProcesoAvance
        {
            public int ProcesoID { get; set; }
            public string ProcesoDescripcion { get; set; }
            public decimal EstadoPorcentaje { get; set; }
            public int CantidadSalida { get; set; }
            public int CantidadProceso { get; set; }
            public int CantidadMerma { get; set; }
        }

        [Serializable]
        private class ResumenProceso
        {            
            public string Etiqueta { get; set; }
            public string Talla { get; set; }
            public int CantidadSalida { get; set; }
            public int CantidadPrendasProgramadas { get; set; }            
        }

        [Serializable]
        private class DetalleActividad
        {
            public int ActividadID { get; set; }
            public string ActividadDescripcion { get; set; }
            public int SectorID { get; set; }
            public string SectorDescripcion { get; set; }
            public int LineaID { get; set; }
            public string LineaDescripcion { get; set; }
            public decimal EstadoPorcentaje { get; set; }
            public int CantidadSalida { get; set; }
            public int CantidadProceso { get; set; }
            public int CantidadMerma { get; set; }
        }

        [Serializable]
        private class ResumenActividad
        {
            public string Etiqueta { get; set; }
            public string Talla { get; set; }
            public int CantidadSalida { get; set; }
            public int CantidadPrendasProgramadas { get; set; }
        }

        /// <summary>
        /// Listado de Rutas Destino.
        /// </summary>
        private List<ProcesoAvance> ListProcesoResumenTemp
        {
            get
            {
                return Session["ListProcesoResumenTemp"] == null ? null : (List<ProcesoAvance>)Session["ListProcesoResumenTemp"];
            }
            set
            {
                Session["ListProcesoResumenTemp"] = value;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Master.ActualizaMenu(MenuPrincipal.Produccion, (int)MenuProduccion.ConsultaAvanceActividades);
                Master.AgregarBreadcrumb("Avance de Actividades", "#", true);
                Master.AgregarBreadcrumb("Consulta", "#", false);

                
                ListProcesoResumenTemp = new List<ProcesoAvance>();
                ListarProcesos();
            }
        }

        protected void btnBuscar_Click(object sender, EventArgs e)
        {
            try
            {  
                gvListadoActividad.DataSource = null;
                gvListadoActividad.DataBind();

                gvListadoResumen.DataSource = null;
                gvListadoResumen.DataBind();

                gvListadoResumenActividad.DataSource = null;
                gvListadoResumenActividad.DataBind();

                ListProcesoResumenTemp = new List<ProcesoAvance>();
                ListarProcesos();
                txtPrendasProgramadas.Text = PrendasProgramadas.ToString();
            }
            catch (Exception x)
            {
                
            }
        }

        private void ListarProcesos()
        {
            database = new TablasDataContext();
            List<TG_Proceso> ListProcesos = new List<TG_Proceso>();

            var ordenProduccion = from detalles in database.PR_OrdenProduccionDetalle
                                  where detalles.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado
                                  group detalles by detalles.OrdPro_Id into g
                                  select new
                                  {
                                      CodigoPedido = g.Key,
                                      PrendasProducir = g.Sum(c => c.OrdProDet_CantidadProducida),
                                      PrendasSolicitadas = g.Sum(c => c.OrdProDet_CantidadSolicitada)
                                  };

            if (ordenProduccion.ToList().Count > 0)
            {
                PrendasProgramadas = ordenProduccion.ToList()[0].PrendasProducir.Value;
            }

            var rutasEstilos = database.DE_RutaProduccion.ToList().FindAll(c => c.Estilo_Id == OrdenProduccionSearch1.EstiloSeleccionado);

            var rutasEstilosOrdenado = rutasEstilos.OrderBy(c => c.Ruta_Orden);

            foreach (var item in rutasEstilosOrdenado)
            {
                if (!ListProcesos.Exists(c => c.Proceso_Id == item.Proceso_Id))
                {
                    ListProcesos.Add(new TG_Proceso()
                    {
                        Proceso_Id = item.Proceso_Id,
                        Proceso_Descripcion = item.TG_Actividad.TG_Proceso.Proceso_Descripcion
                    });
                }
            }

            foreach (var proceso in ListProcesos)
            {
                int cantidadIngreso = CantidadIngresadaProceso(rutasEstilos, proceso.Proceso_Id);
                int cantidadSalida = CantidadSalidaProceso(rutasEstilos, proceso.Proceso_Id);

                ListProcesoResumenTemp.Add(new ProcesoAvance()
                    {
                        ProcesoID = proceso.Proceso_Id,
                        ProcesoDescripcion = proceso.Proceso_Descripcion,
                        CantidadProceso = cantidadIngreso - cantidadSalida,
                        CantidadSalida = cantidadSalida,
                        CantidadMerma = 0
                    });
            }

            gvListadoProcesos.DataSource = ListProcesoResumenTemp;
            gvListadoProcesos.DataBind();
        }
        
        private int CantidadIngresadaProceso(List<DE_RutaProduccion> rutasEstilos, int proceso_Id)
        {
            var actividadIngreso = rutasEstilos.FirstOrDefault(c => c.Proceso_Id == proceso_Id);
            var actividadIngresoParalelo = rutasEstilos.FirstOrDefault(c => c.Actividad_Id != actividadIngreso.Actividad_Id && c.Ruta_Orden == actividadIngreso.Ruta_Orden);

            //Buscar acumulados para la actividad
            var acumuladoActividadIngreso = database.PR_MovimientoAcumulado.ToList().FindAll(c => c.Proceso_Id == actividadIngreso.Proceso_Id &&
                                                                                    c.Actividad_Id == actividadIngreso.Actividad_Id &&
                                                                                    c.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado);
            //Buscar acumulados para la activdades en paralelo
            List<PR_MovimientoAcumulado> acumuladoActividadIngresoParalelo = null;
            if (actividadIngresoParalelo != null)
            {
                acumuladoActividadIngresoParalelo = database.PR_MovimientoAcumulado.ToList().FindAll(c => c.Proceso_Id == actividadIngresoParalelo.Proceso_Id &&
                                                                                        c.Actividad_Id == actividadIngresoParalelo.Actividad_Id &&
                                                                                        c.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado);
            }

            //Se realiza la suma de cantidad de ingreso
            int cantidadIngreso = acumuladoActividadIngreso.Sum(c => c.MovAcu_Ingreso);
            int cantidadIngresoParalelo = (actividadIngresoParalelo != null ? acumuladoActividadIngresoParalelo.Sum(c => c.MovAcu_Ingreso) : 0);

            return (actividadIngresoParalelo != null ? Math.Min(cantidadIngreso, cantidadIngresoParalelo) : cantidadIngreso);
        }

        private int CantidadSalidaProceso(List<DE_RutaProduccion> rutasEstilos, int proceso_Id)
        {
            var actividadSalida = rutasEstilos.LastOrDefault(c => c.Proceso_Id == proceso_Id);
            var actividadSalidaParalelo = rutasEstilos.FirstOrDefault(c => c.Actividad_Id != actividadSalida.Actividad_Id && c.Ruta_Orden == actividadSalida.Ruta_Orden);

            //Buscar acumulados para la actividad
            var acumuladoActividadSalida = database.PR_MovimientoAcumulado.ToList().FindAll(c => c.Proceso_Id == actividadSalida.Proceso_Id &&
                                                                                    c.Actividad_Id == actividadSalida.Actividad_Id &&
                                                                                    c.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado);
            //Buscar acumulados para la activdades en paralelo
            List<PR_MovimientoAcumulado> acumuladoActividadSalidaParalelo = null;
            if (actividadSalidaParalelo != null)
            {
                acumuladoActividadSalidaParalelo = database.PR_MovimientoAcumulado.ToList().FindAll(c => c.Proceso_Id == actividadSalidaParalelo.Proceso_Id &&
                                                                                        c.Actividad_Id == actividadSalidaParalelo.Actividad_Id &&
                                                                                        c.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado);
            }

            //Se realiza la suma de cantidad salida
            int cantidadSalida = acumuladoActividadSalida.Sum(c => c.MovAcu_Proceso);
            int cantidadSalidaParalelo = (actividadSalidaParalelo != null ? acumuladoActividadSalidaParalelo.Sum(c => c.MovAcu_Ingreso) : 0);

            return (actividadSalidaParalelo != null ? Math.Min(cantidadSalida, cantidadSalidaParalelo) : cantidadSalida);
        }

        protected void gvListadoProcesos_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                var proceso = (ProcesoAvance)(e.Row.DataItem);
                double percentage = (Convert.ToDouble(proceso.CantidadSalida) / Convert.ToDouble(PrendasProgramadas))*100.00;
                 e.Row.Cells[2].Text = "<div style= \"WIDTH: 100%\"><div " + 
                               "style= 'BACKGROUND-COLOR:RED;HEIGHT: 10px;WIDTH:"+
                               percentage + "%'></div>" + percentage.ToString("0.00") + "%</div> ";
            }
        }

        private void ActualizarSeleccionGrilla(GridView gv)
        {
            if (gv.SelectedIndex > -1)
                foreach (GridViewRow row in gv.Rows)
                {
                    if (row.Cells[0].Controls.Count > 0)
                    {
                        ImageButton img = (ImageButton)row.Cells[0].Controls[0];
                        if ((row.RowIndex == gv.SelectedIndex))
                        {
                            img.ImageUrl = @"~/images/selected.png";
                        }
                        else
                        {
                            img.ImageUrl = @"~/images/unselected.png";
                        }
                    }
                }
        }

        protected void gvListadoProcesos_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.ProcesoID = (int)gvListadoProcesos.DataKeys[gvListadoProcesos.SelectedIndex]["ProcesoID"];
            ActualizarSeleccionGrilla(gvListadoProcesos);
            
            ListarResumenProceso(this.ProcesoID);
            ListarActividad(this.ProcesoID);

            gvListadoResumenActividad.DataSource = null;
            gvListadoResumenActividad.DataBind();
        }

        private void ListarResumenProceso(int ProcesoID)
        {
            TablasDataContext database = new TablasDataContext();
            List<ResumenProceso> lstResumenProceso = new List<ResumenProceso>();


            var rutasEstilos = database.DE_RutaProduccion.ToList().FindAll(c => c.Estilo_Id == OrdenProduccionSearch1.EstiloSeleccionado);

            if (rutasEstilos != null && rutasEstilos.Count > 0)
            {
                //Buscar Ultima Actividad por Proceso
                var actividad = rutasEstilos.FindLast(c => c.Proceso_Id == ProcesoID);

                //Buscar Actividad en el Acumulado
                var actividades = database.PR_MovimientoAcumulado.ToList().FindAll(c => c.Proceso_Id == actividad.Proceso_Id &&
                                                                                        c.Actividad_Id == actividad.Actividad_Id &&
                                                                                        c.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado);

                var listaDetalle = from detalles in database.PR_OrdenProduccionDetalle
                                   where detalles.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado
                                   select detalles;

                int cantidadSalida = 0;
                foreach (var ordenDetalle in listaDetalle.ToList())
                {
                    cantidadSalida = actividades.FindAll(x => x.MovAcu_Color.ToUpper() == ordenDetalle.OrdProDet_Color.ToUpper() &&
                                                              x.MovAcu_Talla.ToUpper() == ordenDetalle.OrdProDet_Talla.ToUpper()).Sum(c => c.MovAcu_Proceso);
                    lstResumenProceso.Add(new ResumenProceso()
                    {
                        Etiqueta = ordenDetalle.OrdProDet_Color.ToUpper(),
                        Talla = ordenDetalle.OrdProDet_Talla.ToUpper(),
                        CantidadSalida = cantidadSalida,
                        CantidadPrendasProgramadas = ordenDetalle.OrdProDet_CantidadProducida.Value
                    });
                }
            }

            gvListadoResumen.DataSource = lstResumenProceso;
            gvListadoResumen.DataBind();
        }

        protected void gvListadoResumen_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                var resumen = (ResumenProceso)(e.Row.DataItem);
                double percentage = (Convert.ToDouble(resumen.CantidadSalida) / Convert.ToDouble(resumen.CantidadPrendasProgramadas)) * 100.00;
                e.Row.Cells[2].Text = "<div style= \"WIDTH: 100%\"><div " +
                              "style= 'BACKGROUND-COLOR:RED;HEIGHT: 10px;WIDTH:" +
                              percentage + "%'></div>" + percentage.ToString("0.00") + "%</div> ";
            }
        }

        private void ListarActividad(int ProcesoID)
        {
            database = new TablasDataContext();

            //Buscar Actividad en el Acumulado
            var actividades = database.PR_MovimientoAcumulado.ToList().FindAll(c => c.Proceso_Id == ProcesoID &&
                                                                                    c.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado);

            var rutasEstilos = database.DE_RutaProduccion.ToList().FindAll(c => c.Estilo_Id == OrdenProduccionSearch1.EstiloSeleccionado && c.Proceso_Id == ProcesoID);

            List<DetalleActividad> lstResumentActividad = new List<DetalleActividad>();

            foreach (var actividadRuta in rutasEstilos)
            {
                foreach (var actividad in actividades.FindAll(c => c.Actividad_Id == actividadRuta.Actividad_Id))
                {
                    lstResumentActividad.Add(new DetalleActividad()
                    {
                        ActividadID = actividadRuta.TG_Actividad.Actividad_Id,
                        ActividadDescripcion = actividadRuta.TG_Actividad.Actividad_Descripcion,
                        SectorID = actividad.Sector_Id,
                        SectorDescripcion = actividad.Sector_Nombre,
                        LineaID = actividad.Linea_Id,
                        LineaDescripcion = actividad.Linea_Descripcion,
                        CantidadProceso = actividad.MovAcu_Ingreso - actividad.MovAcu_Proceso,
                        CantidadSalida = actividad.MovAcu_Proceso,
                        CantidadMerma = actividad.MovAcu_Merma
                    });
                }
            }

            gvListadoActividad.DataSource = lstResumentActividad;
            gvListadoActividad.DataBind();
        }

        protected void gvListadoActividad_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                var resumen = (DetalleActividad)(e.Row.DataItem);
                double percentage = (Convert.ToDouble(resumen.CantidadSalida) / Convert.ToDouble(PrendasProgramadas)) * 100.00;
                e.Row.Cells[4].Text = "<div style= \"WIDTH: 100%\"><div " +
                              "style= 'BACKGROUND-COLOR:RED;HEIGHT: 10px;WIDTH:" +
                              percentage + "%'></div>" + percentage.ToString("0.00") + "%</div> ";
            }
        }

        protected void gvListadoActividad_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.ActividadID = (int)gvListadoActividad.DataKeys[gvListadoActividad.SelectedIndex]["ActividadID"];
            ActualizarSeleccionGrilla(gvListadoActividad);

            ListarResumenActividad(this.ProcesoID, this.ActividadID);
        }

        private void ListarResumenActividad(int ProcesoID,  int ActividadID)
        {
            TablasDataContext database = new TablasDataContext();
                        
            //Buscar Actividad en el Acumulado
            var actividades = database.PR_MovimientoAcumulado.ToList().FindAll(c => c.Proceso_Id == ProcesoID &&
                                                                                    c.Actividad_Id == ActividadID &&
                                                                                    c.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado);

            var listaDetalle = from detalles in database.PR_OrdenProduccionDetalle
                               where detalles.OrdPro_Id == OrdenProduccionSearch1.CodigoSeleccionado
                               select detalles;

            var lstDetalle = listaDetalle.ToList();

            List<ResumenActividad> lstResumenActividad = new List<ResumenActividad>();

            int cantidadSalida = 0;
            foreach (var ordenDetalle in listaDetalle.ToList())
            {
                cantidadSalida = actividades.FindAll(x => x.MovAcu_Color.ToUpper() == ordenDetalle.OrdProDet_Color.ToUpper() &&
                                                          x.MovAcu_Talla.ToUpper() == ordenDetalle.OrdProDet_Talla.ToUpper()).Sum(c => c.MovAcu_Proceso);
              
                lstResumenActividad.Add(new ResumenActividad()
                {
                    Etiqueta = ordenDetalle.OrdProDet_Color.ToUpper(),
                    Talla = ordenDetalle.OrdProDet_Talla.ToUpper(),
                    CantidadSalida = cantidadSalida,
                    CantidadPrendasProgramadas = ordenDetalle.OrdProDet_CantidadProducida.Value
                });
            }            

            gvListadoResumenActividad.DataSource = lstResumenActividad;
            gvListadoResumenActividad.DataBind();
        }

        protected void gvListadoResumenActividad_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                var resumen = (ResumenActividad)(e.Row.DataItem);
                double percentage = (Convert.ToDouble(resumen.CantidadSalida) / Convert.ToDouble(resumen.CantidadPrendasProgramadas)) * 100.00;
                e.Row.Cells[2].Text = "<div style= \"WIDTH: 100%\"><div " +
                              "style= 'BACKGROUND-COLOR:RED;HEIGHT: 10px;WIDTH:" +
                              percentage + "%'></div>" + percentage.ToString("0.00") + "%</div> ";
            }
        }
    }
}